import { bibtexFor, getPaperBySlug, plainCitationFor, risFor } from "@autoscholar/core"; import { parseBib } from "@autoscholar/qa"; import { publicArtifactKey } from "@autoscholar/storage"; import type { Metadata } from "next"; import Link from "next/link"; import { notFound } from "next/navigation"; import { CopyButton } from "@/components/CopyButton"; import { Disclosure } from "@/components/Disclosure"; import { PaperCard } from "@/components/PaperCard"; import { PdfViewer } from "@/components/PdfViewer"; import { StatusBadge } from "@/components/StatusBadge"; import { Tabs } from "@/components/Tabs"; import { disciplineLabel, fmtBytes, fmtDate, modeLabel, shortHash } from "@/lib/format"; import { t } from "@/lib/i18n"; import { db, storage } from "@/lib/server/db"; export const dynamic = "force-dynamic"; async function load(slug: string) { try { return await getPaperBySlug(db(), slug); } catch { return null; } } export async function generateMetadata({ params }: { params: Promise<{ slug: string }> }): Promise { const { slug } = await params; const p = await load(slug); if (!p) return { title: "Paper not found" }; const base = process.env.APP_BASE_URL ?? "http://localhost:8470"; return { title: p.version.title, description: p.version.abstract.slice(0, 300), alternates: { canonical: `/research/${p.paper.slug}` }, robots: p.paper.synthetic ? { index: false, follow: false } : undefined, openGraph: { title: p.version.title, description: p.version.abstract.slice(0, 300), type: "article", url: `${base}/research/${p.paper.slug}`, publishedTime: p.version.publishedAt.toISOString(), }, other: { citation_title: p.version.title, citation_publication_date: p.version.publishedAt.toISOString().slice(0, 10), citation_technical_report_number: p.paper.publicId, citation_technical_report_institution: "AutoScholar.ai", citation_pdf_url: `${base}${p.version.pdfPublicPath}`, }, }; } type ArtifactEntry = { path: string; kind: string; sha256: string; bytes: number; contentType: string; publicPath: string; }; function Dl({ a }: { a: ArtifactEntry }) { return (
  • {a.path} {fmtBytes(a.bytes)} · {shortHash(a.sha256, 8)}
  • ); } export default async function PaperPage({ params }: { params: Promise<{ slug: string }> }) { const { slug } = await params; const p = await load(slug); if (!p) notFound(); const base = process.env.APP_BASE_URL ?? "http://localhost:8470"; const v = p.version; const meta = v.metadata as Record; const withdrawn = meta.artifactsWithdrawn === true; const set = withdrawn ? [] : v.artifactSet; const url = `${base}/research/${p.paper.slug}`; const pub = new Date(v.publishedAt); const cite = { publicId: p.paper.publicId, title: v.title, year: pub.getUTCFullYear(), month: pub.getUTCMonth() + 1, versionNo: v.versionNo, url, keywords: v.keywords, abstract: v.abstract, }; const figures = set.filter((a) => a.kind === "figure" && /\.(png|svg)$/i.test(a.path)); const pdfFigures = set.filter((a) => a.kind === "figure" && /\.pdf$/i.test(a.path)); const tex = set.filter((a) => a.kind === "manuscript" && /\.(tex|bib|cls|sty)$/i.test(a.path)); const code = set.filter((a) => a.kind === "code"); const data = set.filter((a) => a.kind === "data"); const results = set.filter((a) => a.kind === "result" || a.kind === "table"); const prov = (v.provenance ?? {}) as Record; const qa = (v.qaSummary ?? {}) as { gates?: Array<{ gate: string; status: string; severity: string; message: string }>; warnings?: string[]; policyVersion?: string; evaluatedAt?: string; }; let bib: ReturnType = []; const bibEntry = set.find((a) => a.path === "sources/references.bib"); if (bibEntry) { try { bib = parseBib( (await storage().get(publicArtifactKey(p.paper.publicId, v.versionNo, bibEntry.path))).toString( "utf8", ), ); } catch { bib = []; } } const jsonLd = { "@context": "https://schema.org", "@type": "ScholarlyArticle", headline: v.title, name: v.title, abstract: v.abstract, keywords: v.keywords.join(", "), datePublished: v.publishedAt.toISOString(), dateModified: p.paper.updatedAt.toISOString(), author: { "@type": "Organization", name: "AutoScholar (AI-generated research)", url: base }, publisher: { "@type": "Organization", name: "AutoScholar.ai", url: base }, identifier: p.paper.publicId, url, isAccessibleForFree: true, ...(set.length ? { encoding: { "@type": "MediaObject", contentUrl: `${base}${v.pdfPublicPath}`, encodingFormat: "application/pdf", }, } : {}), about: disciplineLabel(p.paper.discipline), version: v.versionNo, ...(p.retraction ? { creativeWorkStatus: "Retracted" } : {}), }; return (
    {/* biome-ignore lint/security/noDangerouslySetInnerHtml: JSON-LD built from server data */}